﻿///////////////////////////////////////////////////////////////////////////////////////////////
// System.Text.Parsing - © 2011 Sebastien Pellizzari
// Released under the MIT License (http://www.opensource.org/licenses/mit-license.php)
///////////////////////////////////////////////////////////////////////////////////////////////

namespace System.Text.Parsing
{
    /// <summary>Represents a token location for text data.</summary>
    public struct TextLocation
    {
        private readonly int _index;        // Index of the text in source data.
        private readonly int _lineNumber;   // Line number.
        private readonly int _columnNumber; // Column number.

        //-----------------------------------------------------------------------
        //     Properties
        //-----------------------------------------------------------------------

        /// <summary>Gets the index of the location in the source data, starting at 0.</summary>
        public int Index { get { return _index; } }
        /// <summary>Gets the line number of the location, starting at 1.</summary>
        public int LineNumber { get { return _lineNumber; } }
        /// <summary>Gets the column number of the location, starting at 1.</summary>
        public int ColumnNumber { get { return _columnNumber; } }

        /// <summary>Gets a <see cref="TextLocation"/> value that represents an unknown location.</summary>
        public static TextLocation Unknown { get { return new TextLocation(-1, -1, -1); } }

        //-----------------------------------------------------------------------
        //     Constructors
        //-----------------------------------------------------------------------

        /// <summary>Initializes a value of type <see cref="TextLocation"/>.</summary>
        /// <param name="index">The index of the location in the source data.</param>
        /// <param name="lineNumber">The line number of the location.</param>
        /// <param name="columnNumber">The column number of the location.</param>
        public TextLocation(int index, int lineNumber, int columnNumber)
        {
            _index = index;
            _lineNumber = lineNumber;
            _columnNumber = columnNumber;
        }

        //-----------------------------------------------------------------------
        //     Methods
        //-----------------------------------------------------------------------

        /// <summary>Returns the text location that is closest to the beginning of the source data.</summary>
        public static void Min(ref TextLocation a, ref TextLocation b, out TextLocation result)
        {
            if (a._index < b._index) result = a;
            else result = b;
        }

        /// <summary>Returns the text location that is closest to the beginning of the source data.</summary>
        public static TextLocation Min(TextLocation a, TextLocation b)
        {
            TextLocation result;
            Min(ref a, ref b, out result);
            return result;
        }

        /// <summary>Returns the text location that is farthest from the beginning of the source data.</summary>
        public static void Max(ref TextLocation a, ref TextLocation b, out TextLocation result)
        {
            if (a._index > b._index) result = a;
            else result = b;
        }

        /// <summary>Returns the text location that is farthest from to the beginning of the source data.</summary>
        public static TextLocation Max(TextLocation a, TextLocation b)
        {
            TextLocation result;
            Max(ref a, ref b, out result);
            return result;
        }
    }
}
